package org.xlp.expression;

import org.xlp.assertion.AssertUtils;
import org.xlp.fraction.BaseFraction;

/**
 * Description: 简单整数乘除法表达式解析器
 * <br/>date: 2024/12/26 19:25
 *
 * @version 1.0
 * @author: xlp
 */
public class SimpleIntMAndDExpressionParser implements IExpressionParser{
    private IExpressionItemParser itemParser;

    /**
     * 构造函数
     * @param expression 要解析的表达式
     * @throws NullPointerException 假如第参数为null或空，则抛出该异常
     */
    public SimpleIntMAndDExpressionParser(String expression){
       this.itemParser = new ExpressionItemParser(expression);
    }

    /**
     * 构造函数
     * @param itemParser 把表达式解析成计算项对的解析器
     * @throws NullPointerException 假如第参数为null，则抛出该异常
     */
    public SimpleIntMAndDExpressionParser(IExpressionItemParser itemParser){
        AssertUtils.isNotNull(itemParser, "itemParser parameter must be not null!");
        this.itemParser = itemParser;
    }

    /**
     * 解析函数
     *
     * @return 返回表达式结果
     * @throws ExpressionParseException 假如表达式不合法，则抛出该异常
     */
    @Override
    public Number parse() throws ExpressionParseException {
        //数据项解析，防止重复解析
        if (itemParser.getExpressionItems() == null){
            // 还未解析表达式项，则进行解析
            itemParser.parse();
        }
        StringArrayIterator iterator = new StringArrayIterator(itemParser.getExpressionItems());
        return calculateItem(iterator);
    }

    private BaseFraction calculateItem(StringArrayIterator iterator) {
        BaseFraction result = BaseFraction.FRACTION_VALUE_OF_0;
        boolean first = true;
        while (iterator.hasNext()) {
            String next = iterator.next();
            switch (next) {
                case MULTIPLY:
                    result = result.multiply(Long.parseLong(iterator.next()));
                    break;
                case DIVISION:
                    result = result.divide(Long.parseLong(iterator.next()));
                    break;
                case PLUS:
                case MINUS:
                case LEFT_BRACKET:
                case RIGHT_BRACKET:
                    throw new ExpressionParseException("该表达式解析器，不能解析：" + next);
                default:

                    if (first) result = new BaseFraction(Long.parseLong(next), 1);
                    first = false;
            }
        }
        return result.getFraction();
    }
}
